home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Caml Light 0.61 / Source / src / compiler / lexer.mlp < prev    next >
Encoding:
Text File  |  1994-07-07  |  6.3 KB  |  259 lines  |  [TEXT/MPS ]

  1. (* The lexer definition *)
  2.  
  3. {
  4. (**) #open "misc";;
  5. (**) #open "parser";;
  6.  
  7. (* For nested comments *)
  8.  
  9. let comment_depth = ref 0;;
  10.  
  11. (* The table of keywords *)
  12.  
  13. let keyword_table = (hashtbl__new 149 : (string, token) hashtbl__t)
  14. ;;
  15.  
  16. do_list (fun (str,tok) -> hashtbl__add keyword_table str tok) [
  17.   "and", AND;
  18.   "as", AS;
  19.   "begin", BEGIN;
  20.   "do", DO;
  21.   "done", DONE;
  22.   "downto", DOWNTO;
  23.   "else", ELSE;
  24.   "end", END;
  25.   "exception", EXCEPTION;
  26.   "for", FOR;
  27.   "fun", FUN;
  28.   "function", FUNCTION;
  29.   "if", IF;
  30.   "in", IN;
  31.   "let", LET;
  32.   "match", MATCH;
  33.   "mutable", MUTABLE;
  34.   "not", NOT;
  35.   "of", OF;
  36.   "or", OR;
  37.   "prefix", PREFIX;
  38.   "rec", REC;
  39.   "then", THEN;
  40.   "to", TO;
  41.   "try", TRY;
  42.   "type", TYPE;
  43.   "value", VALUE;
  44.   "where", WHERE;
  45.   "while", WHILE;
  46.   "with", WITH
  47. ];;
  48.  
  49. let add_infix s =
  50.   hashtbl__add keyword_table s (INFIX s)
  51. ;;
  52.  
  53. let remove_infix s =
  54.   hashtbl__remove keyword_table s
  55. ;;
  56.  
  57. do_list add_infix
  58.   ["quo"; "mod"; "land"; "lor"; "lxor"; "lsl"; "lsr"; "asr"]
  59. ;;
  60.  
  61. (* To buffer string literals *)
  62.  
  63. let initial_string_buffer = create_string 256;;
  64. let string_buff = ref initial_string_buffer;;
  65. let string_index = ref 0;;
  66.  
  67. let reset_string_buffer () =
  68.   string_buff := initial_string_buffer;
  69.   string_index := 0;
  70.   ()
  71. ;;
  72.  
  73. let store_string_char c =
  74.   if !string_index >= string_length (!string_buff) then begin
  75.     let new_buff = create_string (string_length (!string_buff) * 2) in
  76.       blit_string (!string_buff) 0 new_buff 0 (string_length (!string_buff));
  77.       string_buff := new_buff
  78.   end;
  79.   set_nth_char (!string_buff) (!string_index) c;
  80.   incr string_index
  81. ;;
  82.  
  83. let get_stored_string () =
  84.   let s = sub_string (!string_buff) 0 (!string_index) in
  85.     string_buff := initial_string_buffer;
  86.     s
  87. ;;
  88.  
  89. (* To translate escape sequences *)
  90.  
  91. let char_for_backslash = function
  92. #ifdef macintosh
  93.     `n` -> `\013`
  94.   | `r` -> `\010`
  95. #else
  96.     `n` -> `\010`
  97.   | `r` -> `\013`
  98. #endif
  99.   | `b` -> `\008`
  100.   | `t` -> `\009`
  101.   | c   -> c
  102. ;;
  103.  
  104. let char_for_decimal_code lexbuf i =
  105.   char_of_int(100 * (int_of_char(get_lexeme_char lexbuf i) - 48) +
  106.                10 * (int_of_char(get_lexeme_char lexbuf (i+1)) - 48) +
  107.                     (int_of_char(get_lexeme_char lexbuf (i+2)) - 48))
  108. ;;
  109.  
  110. let saved_string_start = ref 0;;
  111.  
  112. }
  113.  
  114. #ifdef unix
  115. #define ACCENTED `\192`-`\214` `\216`-`\246` `\248`-`\255`
  116. #endif
  117. #ifdef macintosh
  118. #define ACCENTED `\128`-`\159` `\174`-`\175` `\190`-`\191` `\203`-`\207` `\216`-`\217` `\222`-`\223` `\229`-`\239` `\241`-`\244`
  119. #endif
  120. #ifdef msdos
  121. #define ACCENTED `\128`-`\154` `\160`-`\165`
  122. #endif
  123.  
  124. rule Main = parse
  125.     [` ` `\010` `\013` `\009` `\026` `\012`] +
  126.       { Main lexbuf }
  127.   | [`A`-`Z` `a`-`z` ACCENTED ]
  128.     ( `_` ? [`A`-`Z` `a`-`z` ACCENTED `'` (*'*) `0`-`9` ] ) *
  129.       { let s = get_lexeme lexbuf in
  130.           try
  131.             hashtbl__find keyword_table s
  132.           with Not_found ->
  133.             IDENT s }
  134.   | [`0`-`9`]+
  135.     | `0` [`x` `X`] [`0`-`9` `A`-`F` `a`-`f`]+
  136.     | `0` [`o` `O`] [`0`-`7`]+
  137.     | `0` [`b` `B`] [`0`-`1`]+
  138.       { INT (int_of_string(get_lexeme lexbuf)) }
  139.   | [`0`-`9`]+ (`.` [`0`-`9`]*)? ([`e` `E`] [`+` `-`]? [`0`-`9`]+)?
  140.       { FLOAT (float_of_string(get_lexeme lexbuf)) }
  141.   | "\""
  142.       { reset_string_buffer();
  143.         (* Start of token is start of string. *)
  144.         saved_string_start := lexbuf.lex_start_pos;
  145.         String lexbuf;
  146.         lexbuf.lex_start_pos <- !saved_string_start;
  147.         STRING (get_stored_string()) }
  148.   | "`"
  149.       { CHAR (Char lexbuf) }
  150.   | "(*"
  151.       { comment_depth := 1; Comment lexbuf; Main lexbuf }
  152.   | "#" { SHARP }
  153.   | "!" { BANG }
  154.   | "!=" { COMPARISON "!=" }
  155.   | "&" { AMPERSAND }
  156.   | "'" { QUOTE }
  157.   | "(" { LPAREN }
  158.   | ")" { RPAREN }
  159.   | "*" { STAR }
  160.   | "*." { MULTIPLICATIVE "*." }
  161.   | "+" { ADDITIVE "+" }
  162.   | "+." { ADDITIVE "+." }
  163.   | "," { COMMA }
  164.   | "-" { SUBTRACTIVE "-" }
  165.   | "-." { SUBTRACTIVE "-." }
  166.   | "->" { MINUSGREATER }
  167.   | "." { DOT }
  168.   | ".." { DOTDOT }
  169.   | ".(" { DOTLPAREN }
  170.   | "/" { MULTIPLICATIVE "/" }
  171.   | "/." { MULTIPLICATIVE "/." }
  172.   | ":" { COLON }
  173.   | "::" { COLONCOLON }
  174.   | ":=" { COLONEQUAL }
  175.   | ";" { SEMI }
  176.   | ";;" { SEMISEMI }
  177.   | "<" { COMPARISON "<" }
  178.   | "<." { COMPARISON "<." }
  179.   | "<-" { LESSMINUS }
  180.   | "<=" { COMPARISON "<=" }
  181.   | "<=." { COMPARISON "<=." }
  182.   | "<>" { COMPARISON "<>" }
  183.   | "<>." { COMPARISON "<>." }
  184.   | "=" { EQUAL }
  185.   | "=." { COMPARISON "=." }
  186.   | "==" { EQUALEQUAL }
  187.   | ">" { COMPARISON ">" }
  188.   | ">." { COMPARISON ">." }
  189.   | ">=" { COMPARISON ">=" }
  190.   | ">=." { COMPARISON ">=." }
  191.   | ">]" { GREATERRBRACKET }
  192.   | "@" { CONCATENATION "@" }
  193.   | "[" { LBRACKET }
  194.   | "[|" { LBRACKETBAR }
  195.   | "[<" { LBRACKETLESS }
  196.   | "]" { RBRACKET }
  197.   | "^" { CONCATENATION "^" }
  198.   | "_" { UNDERSCORE }
  199.   | "__" { UNDERUNDER }
  200.   | "{" { LBRACE }
  201.   | "|" { BAR }
  202.   | "|]" { BARRBRACKET }
  203.   | "}" { RBRACE }
  204.   | eof { EOF }
  205.   | _
  206.       { raise (Lexical_error("illegal character",
  207.                             get_lexeme_start lexbuf, get_lexeme_end lexbuf)) }
  208.  
  209. and Comment = parse
  210.     "(*"
  211.       { comment_depth := succ !comment_depth; Comment lexbuf }
  212.   | "*)"
  213.       { comment_depth := pred !comment_depth;
  214.         if !comment_depth > 0 then Comment lexbuf }
  215.   | "\""
  216.       { reset_string_buffer();
  217.         String lexbuf;
  218.         reset_string_buffer();
  219.         Comment lexbuf }
  220.   | "`" [^ `\\` `\``] "`"
  221.       { Comment lexbuf }
  222.   | "`" `\\` [`\\` `\`` `n` `t` `b` `r`] "`"
  223.       { Comment lexbuf }
  224.   | "`" `\\` [`0`-`9`] [`0`-`9`] [`0`-`9`] "`"
  225.       { Comment lexbuf }
  226.   | eof
  227.       { raise (Lexical_error("comment not terminated", -1, -1)) }
  228.   | _
  229.       { Comment lexbuf }
  230.  
  231. and Char = parse
  232.     [^ `\\` `\``] "`"
  233.       { get_lexeme_char lexbuf 0 }
  234.   | `\\` [`\\` `\`` `n` `t` `b` `r`] "`"
  235.       { char_for_backslash (get_lexeme_char lexbuf 1) }
  236.   | `\\` [`0`-`9`] [`0`-`9`] [`0`-`9`] "`"
  237.       { char_for_decimal_code lexbuf 1 }
  238.   | _
  239.       { raise (Lexical_error("bad character constant",
  240.                             get_lexeme_start lexbuf, get_lexeme_end lexbuf)) }
  241.  
  242. and String = parse
  243.     `"`
  244.       { () }
  245.   | `\\` [` ` `\010` `\013` `\009` `\026` `\012`] +
  246.       { String lexbuf }
  247.   | `\\` [`\\` `"` `n` `t` `b` `r`]
  248.       { store_string_char(char_for_backslash(get_lexeme_char lexbuf 1));
  249.         String lexbuf }
  250.   | `\\` [`0`-`9`] [`0`-`9`] [`0`-`9`]
  251.       { store_string_char(char_for_decimal_code lexbuf 1);
  252.          String lexbuf }
  253.   | eof
  254.       { raise (Lexical_error("string not terminated", -1, -1)) }
  255.   | _
  256.       { store_string_char(get_lexeme_char lexbuf 0);
  257.         String lexbuf }
  258. ;;
  259.